package user_impl

import (
	"encoding/json"
	"errors"
	"fmt"
	"hong/uniapp_server/common/utils"
	"hong/uniapp_server/domain/user"
	"hong/uniapp_server/infrstructure/dao"
	"hong/uniapp_server/resources"
	"net/http"
	"time"

	"github.com/rs/zerolog/log"
)

type UserRepositoryImpl struct {
	userDao *dao.UserDao
}

type WxLoginResponse struct {
	OpenId     string `json:"openid"`
	SessionKey string `json:"session_key"`
	UnionId    string `json:"unionid"`
	ErrCode    int    `json:"errcode"`
	ErrMsg     string `json:"errmsg"`
}

func NewUserRepositoryImpl(userDao *dao.UserDao) *UserRepositoryImpl {
	return &UserRepositoryImpl{userDao: userDao}
}

func (r *UserRepositoryImpl) Login(wxLoginCode string) (*user.UserEntity, error) {
	config := resources.GetYamlConfig()
	var (
		wxAppId = config.Wechat.AppId
		wxAppSecret = config.Wechat.AppSecret
	)
	wxLoginUrl := fmt.Sprintf("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", wxAppId, wxAppSecret, wxLoginCode)
	statusCode, body, err := utils.HttpGet(wxLoginUrl)
	if err != nil {
		log.Error().Msgf("wx login failed, err: %v", err)
		return nil, err
	}
	
	if statusCode != http.StatusOK {
		log.Error().Msgf("wx login failed, status_code: %d", statusCode)
		return nil, errors.New("wx login failed")
	}
	
	// 解析微信登录响应
	var wxLoginResponse WxLoginResponse
	err = json.Unmarshal(body, &wxLoginResponse)
	if err != nil {
		log.Error().Msgf("wx login failed, unmarshal failed, err: %v", err)
		return nil, err
	}
	if wxLoginResponse.ErrCode != 0 {
		log.Error().Msgf("wx login failed, errcode: %d, errmsg: %s", wxLoginResponse.ErrCode, wxLoginResponse.ErrMsg)
		return nil, errors.New("wx login failed")
	}

	// 获取用户信息
	openId := wxLoginResponse.OpenId
	userEntity, _ := r.userDao.GetUserByOpenId(openId)
	now := time.Now()
	if userEntity == nil || userEntity.ID == 0 {
		// 创建用户
		userEntity = &user.UserEntity{
			WxOpenId: &openId,
			LastLoginTime: &now,
			CreatedAt: &now,
		}
		id, err := r.userDao.Insert(userEntity)
		if err != nil {
			log.Error().Msgf("create user failed, err: %v", err)
			return nil, err
		}
		userEntity.ID = id
	} else {
		userEntity.LastLoginTime = &now
		err = r.userDao.UpdateByWxOpenId(openId, userEntity)
		if err != nil {
			log.Error().Msgf("update user failed, err: %v", err)
			return nil, err
		}
	}
	return userEntity, nil
}
